package controller;

import com.google.common.collect.ImmutableMap;
import common.pojo.CommonResult;
import httpclient.HttpClientUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import pojo.PayInfo;
import service.PayInfoService;
import utils.JsonUtil;
import wxPaySdk.WXPay;
import wxPaySdk.WXPayUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;

import java.util.Map;

/**
 * Created by asus on 2018/11/2.
 */
@Controller
@RequestMapping(value = "/wx")
public class WxNotifyController {
    private final Logger log = LoggerFactory.getLogger(WxNotifyController.class);

    @Autowired
    WXPay wxPay;

    @Autowired
    PayInfoService infoService;

    @RequestMapping(value = "notify", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BufferedReader reader = null;
        reader = request.getReader();
        String line = "";
        String xmlString = null;
        StringBuffer inputString = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            inputString.append(line);
        }
        xmlString = inputString.toString();
        request.getReader().close();
        System.out.println("----接收到的数据如下：---" + xmlString);
        log.warn("---接收到的数据如下---" + xmlString);
        xmlString = xmlString.replace("DOCTYPE", "").replace("SYSTEM", "").replace("ENTITY", "").replace("PUBLIC", "");
        xmlString = xmlString.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
        System.out.println("----接收到的数据如下：---" + xmlString);
        Map map=null;
        try {
            map = WXPayUtil.xmlToMap(xmlString);
        }catch (Exception e){
            response.getWriter().write(returnXML("FAIL"));
            response.getWriter().flush();
            response.getWriter().close();
            log.warn("---wxPay --notify---" + 65);
            return;
        }
        if(map.size()==0){
            response.getWriter().write(returnXML("FAIL"));
            response.getWriter().flush();
            response.getWriter().close();
            log.warn("---wxPay --notify---" + 72);
            return;
        }
        log.warn("---wxPay --notify---" + JsonUtil.toJson(map));
        //校验签名，防止数据被外部篡改
        boolean bool = wxPay.isPayResultNotifySignatureValid(map);
        if (bool) {
            response.getWriter().write(this.updatePay(map));
            response.getWriter().flush();
            response.getWriter().close();
            log.warn("---wxPay --notify---" + "success");
        }else {
            response.getWriter().write(returnXML("FAIL"));
            response.getWriter().flush();
            response.getWriter().close();
        }
    }


    private String returnXML(String return_code) {

        return "<xml><return_code><![CDATA["

                + return_code

                + "]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
    }

    public String updatePay(Map map) {
        String returnCode = map.get("return_code").toString();
        String resultCode = map.get("result_code").toString();
        if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
            String out_trade_no = map.get("out_trade_no").toString();
            String transaction_id = map.get("transaction_id").toString();
            int totalFee = NumberUtils.toInt( map.get("total_fee").toString());
            PayInfo payInfo = infoService.getPayInfo(out_trade_no);
            if (payInfo == null) {
                log.warn("---payInfo---此订单--" + payInfo.getOrderCode() + "不存在");
            }
            int num = infoService.updatePayInfo(out_trade_no, transaction_id, JsonUtil.toJson(map),totalFee);
            CommonResult commonResult = HttpClientUtils.post(payInfo.getClientNotifyUrl(), ImmutableMap.of("orderCode", out_trade_no, "transactionId", transaction_id));
            if(num<=0 || commonResult.isNotSuccess()){
                log.warn(commonResult.getMessage());
                log.warn(""+num+"");
               return returnXML("FAIL");
            }
            return returnXML("SUCCESS");
        }
        return returnXML("FAIL");
    }
}
